<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>

  <!-- 

    js的事件轮询机制

    类似问题(js单线程是怎么避免阻塞的,js的同步和异步是怎么执行的)
    在js中,所有的代码分为同步代码和异步代码
      异步代码:整体的script,定时器回调函数,promise.then/catch/finally的回调函数,事件函数,ajax回调函数
      同步代码:除了异步代码都是同步代码
        异步代码还要分为宏任务代码和微任务代码
    微任务:promise.then/catch/finally(js),MutationObserver(js),process.nextTick(node),queueMicrotask(node)
    宏任务:整体的script,setTimeout,事件回调函数,ajax回调函数....

    事件轮询的整体流程
      先执行整体script这个异步
      然后进入script执行其中的同步代码
      当遇到宏任务的时候,把宏任务的交给浏览器对应的管理模块中进行管理(事件管理模块,ajax管理模块,定时器管理模块,其中每一个管理模块都可以认为是浏览器开启的分线程),一旦宏任务需要被执行,则把宏任务的回调函数交给宏任务的回调队列中等待执行
      当遇到微任务的时候,直接把微任务的回调函数交给微任务队列等待执行
      一旦同步代码执行结束,首先清空微任务队列
      开始执行宏任务队列,每次执行完一个宏任务都要再去清空微任务
    ....





    执行顺序:
    script标签是宏任务
      开始解析: 有两个script标签 任务队列有两个宏任务
      开始执行:  
      1 是同步任务 同步任务执行完毕 开始执行当前的微任务 输出2 
      然后又发现一个宏任务(定时器) 但是不执行 因为任务队列还有一个宏任务(第二个script标签)
      执行第二个script标签 输出4
      最后 执行定时器 3

   -->

  <!--   
  <script>
    console.log(1);
    Promise.resolve().then(() => {
      console.log(2);
    });
    setTimeout(() => {
      console.log(3);
    });
  </script>

  <script>
    console.log(4);
  </script> 

  -->



  <script>
    //模拟第一个script标签
    setTimeout(() => {
      console.log(1);
      Promise.resolve().then(() => {
        console.log(2);
      });
      setTimeout(() => {
        console.log(3);
      });
    });

    //模拟第二个script标签
    setTimeout(() => {
      console.log(4);
    });
  </script>





</body>

</html>